package demo6

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

type Pig struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Like  string `json:"like"`
	Hobby string `json:"hobby"`
}

func Test01() {
	// 或者你可以创建一个新的viper实例
	var p Pig

	var runtime_viper = viper.New()
	runtime_viper.SetConfigFile("./config.json")
	for {
		time.Sleep(time.Second * 5) // 每次请求后延迟一下

		if err := runtime_viper.ReadInConfig(); err != nil {
			if _, ok := err.(viper.ConfigFileNotFoundError); ok {
				// 配置文件未找到错误；如果需要可以忽略
				// log.("配置文件未找到错误；如果需要可以忽略")
				fmt.Println("配置文件未找到错误；如果需要可以忽略")

			} else {
				// 配置文件被找到，但产生了另外的错误
				fmt.Sprintln("配置文件被找到，但产生了另外的错误")
			}
		}
		runtime_viper.WatchConfig()
		runtime_viper.OnConfigChange(func(e fsnotify.Event) {
			// 配置文件发生变更之后会调用的回调函数
			fmt.Println("Config file changed:", e.Name)
			time.Sleep(time.Second * 1)
			runtime_viper.Unmarshal(&p)
			fmt.Println(p)
		})
		runtime_viper.Unmarshal(&p)
		fmt.Println(p)
	}

}

func Test02() {
	viper.SetConfigType("yaml") // 或者 viper.SetConfigType("YAML")

	// 任何需要将此配置添加到程序中的方法。
	var yamlExample = []byte(`
	Hacker: true
	name: steve
	hobbies:
	- skateboarding
	- snowboarding
	- go
	clothing:
	jacket: leather
	trousers: denim
	age: 35
	eyes : brown
	beard: true
	`)

	viper.ReadConfig(bytes.NewBuffer(yamlExample))

	viper.Get("name") // 这里会得到 "steve"
	fmt.Println(viper.Get("name"))
	viper.Set("Verbose", true)
	// viper.Set("LogFile", LogFile)
	viper.RegisterAlias("loud", "Verbose") // 注册别名（此处loud和Verbose建立了别名）

	viper.Set("verbose", true) // 结果与下一行相同
	viper.Set("loud", true)    // 结果与前一行相同

	viper.GetBool("loud")                 // true
	fmt.Println(viper.GetBool("verbose")) // true
}

func ViperENV() {
	viper.SetEnvPrefix("spf")
	viper.BindEnv("id")
	os.Setenv("SPF_ID", "13")
	id := viper.Get("id")
	fmt.Println(id)
}

// func ViperFlags() {
// 	serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// 	viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
// }

func ViperPFlag() {
	pflag.Int("flagname", 1234, "help message for flagname")

	pflag.Parse()
	viper.BindPFlags(pflag.CommandLine)

	i := viper.GetInt("flagname") // 从viper而不是从pflag检索值
	fmt.Println(i)
}

func ViperFlag() {
	flag.Int("flagname", 1234, "help message for flagname")
	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
	pflag.Parse()
	viper.BindPFlags(pflag.CommandLine)
	i := viper.GetInt("flagname")
	fmt.Println(i)
}

func ViperCheckFiled() {
	viper.GetString("logfile")
	if viper.GetBool("verbose") {
		fmt.Println("verbose enabled")
	}
}

// 访问嵌套的键
func ViperGetString() {
	var runtime_viper = viper.New()
	runtime_viper.SetConfigFile("./123.json")
	if err := runtime_viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// 配置文件未找到错误；如果需要可以忽略
			// log.("配置文件未找到错误；如果需要可以忽略")
			fmt.Println("配置文件未找到错误；如果需要可以忽略")

		} else {
			// 配置文件被找到，但产生了另外的错误
			fmt.Sprintln("配置文件被找到，但产生了另外的错误")
		}
	}
	v := runtime_viper.GetString("datastore.metric.host")
	fmt.Println(v)
}

// 提取子树
func ViperTree() {
	var runtime_viper = viper.New()
	runtime_viper.SetConfigFile("./111.ini")
	if err := runtime_viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// 配置文件未找到错误；如果需要可以忽略
			// log.("配置文件未找到错误；如果需要可以忽略")
			fmt.Println("配置文件未找到错误；如果需要可以忽略")

		} else {
			// 配置文件被找到，但产生了另外的错误
			fmt.Sprintln("配置文件被找到，但产生了另外的错误")
		}
	}
	cfg1 := runtime_viper.Sub("app.cache1")
	// cache1 := NewCache(cfg1)
	cfg2 := runtime_viper.Sub("app.cache2")
	// cache2 := NewCache(cfg2)
	fmt.Println(cfg1, cfg2)
}
